package com.example.service;

import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.elasticsearch._types.query_dsl.FuzzyQuery;
import co.elastic.clients.elasticsearch._types.query_dsl.Query;
import co.elastic.clients.elasticsearch.core.SearchResponse;
import co.elastic.clients.elasticsearch.core.search.Hit;
import co.elastic.clients.elasticsearch.core.search.TotalHits;
import com.example.pojo.dao.PostIndexRepository;
import com.example.pojo.dto.BossDTO;
import com.example.pojo.dto.PostIndexDTO;
import com.example.pojo.entity.JobRecruiter;
import com.example.pojo.entity.Post;
import com.example.pojo.entity.PostIndex;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.github.pagehelper.Page;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
//import org.springframework.data.elasticsearch.annotations.HighlightField;
import org.springframework.data.elasticsearch.client.elc.ElasticsearchAggregations;
import org.springframework.data.elasticsearch.client.elc.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
import org.springframework.data.elasticsearch.core.IndexOperations;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.Criteria;
import org.springframework.data.elasticsearch.core.query.CriteriaQuery;
import org.springframework.data.elasticsearch.core.query.HighlightQuery;
import org.springframework.data.elasticsearch.core.query.highlight.Highlight;
import org.springframework.data.elasticsearch.core.query.highlight.HighlightField;
import org.springframework.data.elasticsearch.core.query.highlight.HighlightParameters;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

/**
 * @author 小岁
 * @version 2023/10/24 22:00
 */
@Service
public class PostsIndexServiceImpl implements PostsIndexService{

    private static final Logger log = LoggerFactory.getLogger(PostsIndexServiceImpl.class);

    @Autowired
    private PostsService postsService;

    @Autowired
    private RecruiterService recruiterService;
    @Autowired
    private ElasticsearchTemplate elasticsearchTemplate;
     @Autowired
    ElasticsearchClient elasticsearchClient;

    @Autowired
    private PostIndexRepository postIndexRepository;

    @Autowired
    ElasticsearchOperations operations;
    /*初始化索引结构和数据*/


    @Override
    public void initIndex() {
        //处理索引结构
        IndexOperations indexOps = elasticsearchTemplate.indexOps(PostIndex.class);
        if (indexOps.exists()){
            boolean delFlag = indexOps.delete();
            log.info("post_index exists,delete:{}",delFlag);
            indexOps.createWithMapping();
        }else {
            log.info("post_index not exists");
            indexOps.createWithMapping();
        }
//        同步一下数据库表的记录
//        List<Post> postList = postsService.selectAll();
//        List<JobRecruiter> recruiterList = recruiterService.selectAll();
//        PostIndexDTO postIndexDTO = new PostIndexDTO();
//        List<PostIndex> postIndexList =new ArrayList<>();
////
//        if (!postList.isEmpty()){
//            for (Post post : postList) {
//                PostIndex postIndex = new PostIndex();
//                postIndex.setPosId(post.getId());
//
//                //                postIndex.setPosName(post.getPosName());
////                postIndex.setPosKeyword(post.getPosKeyword());
//                postIndex.setPosName(post.getPosName());
//                //职位描述
//                postIndex.setPosDescription(post.getPosDescription());
//                //后加
//                postIndex.setWorkPlace(post.getWorkPlace());
//                //上下限
//                postIndex.setPayFloor(post.getPayFloor());
//                //关键词
//                postIndex.setPosKeyword(post.getPosKeyword());
//                postIndex.setBackground(post.getBackground());
//                //jrName,jrPosition;
//                postIndex.setJrId(post.getJrId());
//                //工作经验
//                postIndex.setExpDemand(post.getExpDemand());
//
//                postIndex.setPayUpper(post.getPayUpper());
//                postIndex.setSpecialty(post.getSpecialty());
//                postIndex.setAgeDemand(post.getAgeDemand());
//                postIndex.setJobBenefits(post.getJobBenefits());
//
//                JobRecruiter jobRecruiter = recruiterService.findById(post.getJrId());
////                postIndex.setCompanyName(jobRecruiter.getCompanyName());
//                //后加
//                postIndex.setCompanyType(jobRecruiter.getCompanyType());
//                postIndex.setRunState(jobRecruiter.getRunState());
//                postIndex.setEmployeesQuantity(jobRecruiter.getEmployeesQuantity());
//
//                postIndexList.add(postIndex);
//            }
//            elasticsearchTemplate.save(postIndexList);
//        }

    }



    @Override
    public SearchHits<PostIndex> findByPosNameOrCompanyNames(String posName, String companyName) {
//        List<PostIndex> postIndexList = new ArrayList<>();
        SearchHits<PostIndex> postIndexSearchHits = null;
        HighlightParameters highlightParameters =  new HighlightParameters.HighlightParametersBuilder().withPreTags("<span style='color:red;font-weight: bold;'>").withPostTags("</span>").withNumberOfFragments(0).build();

        List<HighlightField> highlightFields = new ArrayList<>();
        HighlightField posNames = new HighlightField("pos_name");

        highlightFields.add(posNames);

        HighlightQuery highlightQuery = new HighlightQuery(new Highlight(highlightParameters,highlightFields),PostIndex.class);
        Criteria criteria = new Criteria()
                .and("pos_name").matches(posName);
//                .and("company_name").matches(companyName);
        CriteriaQuery query = new CriteriaQuery(criteria).addSort(Sort.by(Sort.Direction.DESC,"publish_time"));
        query.setHighlightQuery(highlightQuery);
//        return postIndexRepository.findByPosNameOrCompanyName(posName,companyName);
        postIndexSearchHits=operations.search(query,PostIndex.class);
        System.out.println("123456");
        for (SearchHit<PostIndex> postIndexSearchHit : postIndexSearchHits) {
            postIndexSearchHit.getIndex();
        }
        return postIndexSearchHits;
    }

    @Override
    public List<SearchHit<PostIndex>> findByPosNameOrCompanyNameOrPosDescription(String posName, String companyName,String posDescription) {

        return postIndexRepository.findByPosNameOrCompanyNameOrPosDescription(posName,companyName,posDescription);

        }

//    @Component
//    public class ElasticsearchIndexUpdater {
//        @Scheduled(fixedRate =43200000 ) // 每12小时 每小时执行一次3600000
//        public void updateElasticsearchIndex() {
////            long lastSyncTimestamp = getLastSyncTimestamp();
////            List<Post> changedPosts = postsService.findChangedPostsSince(lastSyncTimestamp);
//
//            // 在这里编写更新Elasticsearch索引的逻辑
//            IndexOperations indexOps = elasticsearchTemplate.indexOps(PostIndex.class);
//            if (indexOps.exists()){
//                boolean delFlag = indexOps.delete();
//                log.info("post_index exists,delete:{}",delFlag);
//                indexOps.createWithMapping();
//            }else {
//                log.info("post_index not exists");
//                indexOps.createWithMapping();
//            }
//            //同步一下数据库表的记录
//            List<Post> postList = postsService.selectAll();
//            List<PostIndex> postIndexList =new ArrayList<>();
//
//            if (!postList.isEmpty()){
//                for (Post post : postList) {
//                    PostIndex postIndex = new PostIndex();
//                    postIndex.setPosName(post.getPosName());
//                    postIndex.setPosKeyword(post.getPosKeyword());
//                    postIndex.setPosName(post.getPosName());
//                    postIndex.setPosId(post.getId());
//                    //职位描述
//                    postIndex.setPosDescription(post.getPosDescription());
//                    //后加
//                    postIndex.setWorkPlace(post.getWorkPlace());
//                    //上下限
//                    postIndex.setPayFloor(post.getPayFloor());
//                    //关键词
//                    postIndex.setPosKeyword(post.getPosKeyword());
//                    postIndex.setBackground(post.getBackground());
//                    //jrName,jrPosition;
//                    postIndex.setJrId(post.getJrId());
//                    //工作经验
//                    postIndex.setExpDemand(post.getExpDemand());
//
//                    postIndex.setPayUpper(post.getPayUpper());
//                    postIndex.setSpecialty(post.getSpecialty());
//                    postIndex.setAgeDemand(post.getAgeDemand());
//                    postIndex.setJobBenefits(post.getJobBenefits());
//
//                    JobRecruiter jobRecruiter = recruiterService.findById(post.getJrId());
//                    postIndex.setCompanyName(jobRecruiter.getCompanyName());
//                    //后加
//                    postIndex.setCompanyType(jobRecruiter.getCompanyType());
//                    postIndex.setRunState(jobRecruiter.getRunState());
//                    postIndex.setEmployeesQuantity(jobRecruiter.getEmployeesQuantity());
//
//                    postIndexList.add(postIndex);
//                }
//                elasticsearchTemplate.save(postIndexList);
//            }
//        }
//    }


    //            for (Post post : postList) {
//                PostIndex postIndex = new PostIndex();
//                BeanUtils.copyProperties(post,postIndex);
//                //查找匹配的recruiter
//                //则将companyName设置到PostIndex中 同步到 Elasticsearch 索引中。
//                Optional<JobRecruiter> Recruiter = recruiterList.stream().filter(jobRecruiter -> jobRecruiter.getId().equals(post.getJrId())).findFirst();
//                if (Recruiter.isPresent()){
//                    postIndex.setPosName(Recruiter.get().getCompanyName());
//                }
//                postIndexList.add(postIndex);
//            }
//            elasticsearchTemplate.save(postIndexList);
//            postIndexList.forEach(post->{
//                PostIndex postIndex = new PostIndex();
//                BeanUtils.copyProperties(post,postIndex);
//                postIndexList.add(postIndex);
//            });
//            postIndexList.forEach(System.out::println);
//    @Override
//    public List<SearchHit<PostIndex>> findByPosNameOrCompanyName(String posName,String companyName)  {
//        return postIndexRepository.findByPosNameOrCompanyName(posName,companyName);
////        Query byContent = FuzzyQuery.of(field -> field.field("title").value("设计").fuzziness("1"))._toQuery();
////        SearchResponse<PostIndex> resp = null;
////        try {
////            resp = elasticsearchClient .search(
////                    searchReq -> searchReq.index("post_index").query(byContent), PostIndex.class);
////        } catch (IOException e) {
////            throw new RuntimeException(e);
////        }
////         printResp(resp);
////
////        return (List<SearchHit<PostIndex>>) resp;
//
//
//    }

    private void printResp (SearchResponse<PostIndex> resp){

        TotalHits total = resp.hits().total();
        System.out.println("total："+total);
        List<Hit<PostIndex>> hits = resp.hits().hits();
        for (Hit<PostIndex> hit: hits) {
            PostIndex contentsIndex = hit.source();
            System.out.println(hit.id()+"："+contentsIndex);
        }
    }
//    @Override
//    public List<SearchHit<PostIndex>> findByPosNameOrCompanyName(String search) {
//        return postIndexRepository.findByPosNameOrCompanyName(search);
//    }

    @Override
    public List<SearchHit<PostIndex>> findByPosDescription(String posDescription) {
        return postIndexRepository.findByPosDescription(posDescription);
    }

    @Override
    public List<SearchHit<PostIndex>> findByJrIdAndPosNameOrPosDescriptionOrPosKeyword(Integer jrId,String posName,String posDescription,String posKeyword) {
        return postIndexRepository.findByJrIdAndPosNameOrPosDescriptionOrPosKeyword(jrId,posName,posDescription,posKeyword);
    }

    @Override
    public List<SearchHit<PostIndex>> findByIdOrPosDescription(String id,String posDescription) {
        return postIndexRepository.findByIdOrPosDescription(id,posDescription);
    }
}
